﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace alphabook
{
    class User
    {
        private int id = -1;
        public int ID
        {
            get { return id; }
        }

        private String username;
        public String Username
        {
            get { return username; }
            set { username = value; Update(); }
        }

        private String firstname;
        public String Firstname
        {
            get { return firstname; }
            set { firstname = value; Update(); }
        }

        private String surname;
        public String Surname
        {
            get { return surname; }
            set { surname = value; Update(); }
        }

        private bool stopped = false;
        public Boolean Stopped
        {
            get { return stopped; }
            set { stopped = value; Update(); }
        }


        /// <summary>
        /// Creates an empty user
        /// </summary>
        public User()
        {
        }

        /// <summary>
        /// Creates a new user
        /// </summary>
        /// <param name="username">Username</param>
        /// <param name="firstname">Firstname of user</param>
        /// <param name="surname">Surname of user</param>
        public User(String username, String firstname, String surname)
        {
            this.username = username;
            this.firstname = firstname;
            this.surname = surname;
            this.Insert();
        }

        /// <summary>
        /// Creates an existing user with id, used for fetching
        /// </summary>
        /// <param name="id">User ID</param>
        /// <param name="username">Username</param>
        /// <param name="firstname">Firstname of user</param>
        /// <param name="surname">Surname of user</param>
        public User(int id, String username, String firstname, String surname)
        {
            this.id = id;
            this.username = username;
            this.firstname = firstname;
            this.surname = surname;
        }




        /// <summary>
        /// Update user values
        /// </summary>
        /// <returns>0 - success, 1 - failed</returns>
        private int Update()
        {
            Database db = new Database();
            if (this.id == -1)
            {
                return 0;
            }
            String sql = "UPDATE USER SET username = '" + this.username +
            "', first_name = '" + this.firstname + "', surname = '" + this.surname +
            "', stopped = " + this.stopped + " WHERE user_ID = " + this.id;
            int rows = db.Execute(sql);
            db.Close();
            return Util.checkResult(rows);

        }

        /// <summary>
        /// Saves the user to database
        /// </summary>
        /// <param name="db">Current database connection</param>
        /// <returns>0 - success, -1 - user exists, 1 - other error</returns>
        private int Insert()
        {
            Database db = new Database();
            ArrayList check = db.Query("SELECT * FROM USER WHERE username = '" + this.username + "';");
            if (check.Count == 0)
            {

                int rows = db.Execute("INSERT INTO USER VALUES(null, '" + this.username + "', '" 
                    + this.firstname + "', '" + this.surname + "', 0);");
                ArrayList id = db.Query("SELECT * FROM USER WHERE username = '" + this.username + "';");
                Dictionary<String, object> d = (Dictionary<String, object>)id[0];
                this.id = (int)d["user_ID"];
                db.Close();
                return Util.checkResult(rows);
            }
            else
            {
                this.username = "";
                db.Close();
                return -1;
            }
        }

        /// <summary>
        /// Deletes the user if one has no lent books
        /// </summary>
        /// <param name="id">User ID</param>
        /// <returns>0 - success, -1 - can't delete, 1 - other error </returns>
        public int Delete(int id)
        {

            Loan[] loans = Loan.GetLoansByUser(id);
            if (loans.Length == 0)
            {
                int rows = new Database().Execute("DELETE FROM USER WHERE user_ID = " + id);
                return Util.checkResult(rows);
            }
            else
            {
                return -1;
            }
        }


        /// <summary>
        /// Fetch all users
        /// </summary>
        /// <returns>Array of Users</returns>
        public static User[] getAllUsers()
        {
            Database db = new Database();
            ArrayList result = db.Query("SELECT * FROM USER;");
            db.Close();
            User[] users = new User[result.Count];
            for (int i = 0; i < result.Count; i++)
            {
                Dictionary<String, object> d = (Dictionary<string,object>)result[i];
                users[i] = new User((int)d["user_ID"], (String)d["username"], (String)d["first_name"], (String)d["surname"]);
            }
            return users;
        }

        /// <summary>
        /// Fetch a user by username
        /// </summary>
        /// <param name="username">Username of an User</param>
        /// <returns>Single User</returns>
        public static User getUser(String username)
        {
            Database db = new Database();
            ArrayList result = db.Query("SELECT * FROM USER WHERE username = '" + username + "';");
            db.Close();
            if (result.Count != 0)
            {
                Dictionary<String, object> d = (Dictionary<string, object>)result[0];
                return new User((int)d["user_ID"], (String)d["username"], (String)d["first_name"], (String)d["surname"]);
            }
            else
            {
                return new User();
            }
        }

        /// <summary>
        /// Fetch a user by ID
        /// </summary>
        /// <param name="id">ID of user</param>
        /// <returns>Single User</returns>
        public static User getUser(int id)
        {
            Database db = new Database();
            ArrayList result = db.Query("SELECT * FROM USER WHERE user_ID = " + id + ";");
            db.Close();
            if (result.Count != 0)
            {
            Dictionary<String, object> d = (Dictionary<string, object>)result[0];
            return new User((int)d["user_ID"], (String)d["username"], (String)d["first_name"], (String)d["surname"]);
            }
            else
            {
                return new User();
            }
        }
    }
}
